package com.example.codereview.util;

import com.example.codereview.review.CodeLight;
import com.intellij.ui.JBColor;

import javax.swing.*;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.*;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

public class JavaCodeStyle {

    public static final List<String> KEY_WORD = Arrays.asList(
            "abstract","assert","boolean","break","byte","case","catch","char","class",
            "continue","default","do","double","else","enum","extends","final","finally","float","for","if",
            "implements","import","int","interface","instanceof","long","native","new","package","private","protected","public",
            "return","short","static","strictfp","super","switch","synchronized","this",
            "throw","throws","transient","try","void","volatile","while");


    public static final List<String> SPECIAL_WORD = Arrays.asList("true","false","null");

    private static Map<String, Style> styles = new HashMap<>();


    public static class TextPaneStyle{

        private JTextPane pane;
        //当前代码是否为注释 多行注释
        boolean duoZhuShi = false;
        // 单行注释
        boolean danZhuShi = false;
        //魔法值 字符串
        boolean moFaZhi = false;

        private StyledDocument doc;

        private List<String> codes = new ArrayList<>();

        private StringBuilder builder = new StringBuilder("");

        private List<CodeLight> lights = new ArrayList<>();


        public TextPaneStyle(JTextPane pane, String code){
            this.pane = pane;
            this.doc = this.pane.getStyledDocument();
            if(!ObjectUtils.isEmpty(code)){
                String[] split = code.split("\n");
                this.codes = new ArrayList<>(Arrays.asList(split));
            }
        }

        public void buildText2(){
            for(int k =0 ; k<codes.size(); k++) {
                String codeValue = codes.get(k);
                List<String> ss = IdeaUtils.codeSplit(codeValue);
                for (int i = 0; i < ss.size(); i++) {
                    String s = ss.get(i);
                    String prefixChar = "";
                    for (int j = 0; j < s.length();j++) {
                        char c = s.charAt(j);
                        String codeC = String.valueOf(c);
                        builder.append(codeC);
                        if("\"".equals(codeC) && !this.moFaZhi && !this.duoZhuShi && !this.danZhuShi){
                            this.moFaZhi = true;
                        }else if("\"".equals(codeC) && this.moFaZhi && !this.duoZhuShi && !this.danZhuShi){
                            Style style = mofazhiStyle(pane);
                            insertStr(codeC, style);
                            builder = new StringBuilder();
                            this.moFaZhi = false;
                        }
                        if ("/*".equals(builder.toString())) {
                            this.duoZhuShi = true;
                        }
                        if ("//".equals(builder.toString())) {
                            this.danZhuShi = true;
                        }
                        if (this.duoZhuShi || this.danZhuShi) {
                            Style style = zhushiStyle(pane);
                            insertStr(builder.toString(), style);
                            builder = new StringBuilder();
                        }else if(this.moFaZhi){
                            Style style = mofazhiStyle(pane);
                            insertStr(builder.toString(), style);
                            builder = new StringBuilder();
                        }
                        if ("/".equals(codeC) && "*".equals(prefixChar)) {
                            this.duoZhuShi = false;
                        }

                        prefixChar = codeC;
                    }
                    boolean funcFlag = false;
                    if(i<ss.size()-1 && "(".equals(ss.get(i+1))){
                        funcFlag = true;
                    }
                    //关键字
                    if (keyWord(s)) {
                        Style style = keyWordStyle(pane);
                        insertStr(builder.toString(), style);
                        builder = new StringBuilder();
                    }else if(builder.toString().contains("@")){
                        //注解
                        Style style = zhuJieStyle(pane);
                        insertStr(builder.toString(), style);
                        builder = new StringBuilder();
                    }else if(funcFlag){
                        //方法
                        Style style = funcStyle(pane);
                        insertStr(builder.toString(), style);
                        builder = new StringBuilder();
                    }else {
                        //其他字符
                        insertStr(builder.toString(), defaultStyle(pane));
                        builder = new StringBuilder();
                    }
                }
                this.danZhuShi = false;
                int finalK = k;
                List<CodeLight> collect = this.lights.stream().filter(l -> (finalK + 1) == l.getLineNumber())
                        .sorted(Comparator.comparing(CodeLight::getOffset))
                        .collect(Collectors.toList());
                if(!ObjectUtils.isEmpty(collect)){
                    System.out.println("存在codeLight过滤:"+collect.size());
                    Style style = lightStyle(pane);
                    collect.forEach(l -> {
                        insertStr(l.getValue(), style);
                    });
                }
                if (k < codes.size() - 1) {
                    insertStr("\n", defaultStyle(pane));
                }
            }
            this.pane.setEditable(true);
            this.pane.setCaretPosition(0);
        }

        private boolean nextValueFlag(List<String> ss,int nowIndex,String next){
            if(nowIndex >= ss.size()-1){
                return false;
            }
            String nextS = ss.get(nowIndex+1);
            if(nextS.equals(next)){
                return true;
            }
            if(" ".equals(nextS)) {
                return nextValueFlag(ss, nowIndex+1, next);
            }
            return false;
        }

        private boolean keyWord(String c){
            if(KEY_WORD.contains(c) || SPECIAL_WORD.contains(c)){
                return true;
            }
            try{
                Integer.parseInt(c);
                return true;
            }catch (Exception e){}
            try{
                Long.parseLong(c);
                return true;
            }catch (Exception e){}
            try{
                Float.parseFloat(c);
                return true;
            }catch (Exception e){}
            try{
                Double.parseDouble(c);
                return true;
            }catch (Exception e){}
            return false;
        }


        private void insertStr(String value,Style style){
            try {
                doc.insertString(doc.getLength(), value, style);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        /**
         * 关键字style
         */
        public Style keyWordStyle(JTextPane pane){
            String key = "KeyWord";
            Style keyWord = styles.get(key);
            if(ObjectUtils.isEmpty(keyWord)){
                Style style = pane.addStyle(key, null);
                String themeName = IdeaUtils.getTheme();
                if ("Darcula".equals(themeName)) {
                    // 处理暗色主题逻辑
                    StyleConstants.setForeground(style,new JBColor(new Color(200,116,48),new Color(200,116,48))); // 前景色为蓝色
                } else{
                    // 处理亮色主题逻辑
                    StyleConstants.setForeground(style, JBColor.BLUE); // 前景色为蓝色
                }
                styles.put(key,style);
                keyWord = style;
            }
            return keyWord;
        }

        public Style defaultStyle(JTextPane pane){
            String key = "default";
            Style keyWord = styles.get(key);
            if(ObjectUtils.isEmpty(keyWord)){
                Style style = pane.addStyle(key, null);
                styles.put(key,style);
                keyWord = style;
            }
            return keyWord;
        }


        /**
         * 注解style
         */
        public  Style funcStyle(JTextPane pane){
            String key = "Func";
            Style func = styles.get(key);
            if(ObjectUtils.isEmpty(func)){
                Style style = pane.addStyle(key, null);
                String themeName = IdeaUtils.getTheme();
                if ("Darcula".equals(themeName)) {
                    // 处理暗色主题逻辑
                    StyleConstants.setForeground(style,new JBColor(new Color(151,116,167),new Color(151,116,167))); // 前景色为蓝色
                } else{
                    // 处理亮色主题逻辑
                    StyleConstants.setForeground(style, new JBColor(new Color(200, 55, 156), new Color(200, 55, 156)));
                }
                styles.put(key,style);
                func = style;
            }
            return func;
        }


        /**
         * 注解style
         */
        public  Style zhuJieStyle(JTextPane pane){
            String key = "ZhuJie";
            Style keyWord = styles.get(key);
            if(ObjectUtils.isEmpty(keyWord)){
                Style style = pane.addStyle(key, null);
                StyleConstants.setForeground(style, new JBColor(new Color(183, 143, 29), new Color(183, 143, 29))); // 前景色为蓝色
                styles.put(key,style);
                keyWord = style;
            }
            return keyWord;
        }

        /**
         * 标注 light style
         */
        public  Style lightStyle(JTextPane pane){
            String key = "Light";
            Style keyWord = styles.get(key);
            if(ObjectUtils.isEmpty(keyWord)){
                Style style = pane.addStyle(key, null);
                StyleConstants.setForeground(style, JBColor.RED);
                styles.put(key,style);
                keyWord = style;
            }
            return keyWord;
        }

        /**
         * 注释style
         */
        public  Style zhushiStyle(JTextPane pane){
            String key = "ZhuShi";
            Style keyWord = styles.get(key);
            if(ObjectUtils.isEmpty(keyWord)){
                Style style = pane.addStyle(key, null);
                StyleConstants.setForeground(style, JBColor.GRAY); // 前景色为亮灰
                styles.put(key,style);
                keyWord = style;
            }
            return keyWord;
        }

        /**
         * 魔法值style
         */
        public  Style mofazhiStyle(JTextPane pane){
            String key = "MoFaZhi";
            Style keyWord = styles.get(key);
            if(ObjectUtils.isEmpty(keyWord)){
                Style style = pane.addStyle(key, null);
                StyleConstants.setForeground(style, new JBColor(new Color(6, 125, 23), new Color(6, 125, 23))); // 前景色为亮灰
                styles.put(key,style);
                keyWord = style;
            }
            return keyWord;
        }

    }


    public static void setText(JTextPane pane, String code, List<CodeLight> lights){
        TextPaneStyle textPaneStyle = new TextPaneStyle(pane,code);
        try {
            if(!ObjectUtils.isEmpty(lights)) {
                textPaneStyle.lights = lights;
            }
            textPaneStyle.buildText2();
        }catch (Exception e){
            pane.setText(code);
        }
    }




}
